package com.shop.cloud.upms.admin.controller;

import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.shop.cloud.common.core.constant.CommonConstants;
import com.shop.cloud.common.core.util.R;
import com.shop.cloud.common.data.tenant.TenantContextHolder;
import com.shop.cloud.common.log.annotation.SysLog;
import com.shop.cloud.common.security.annotation.Inside;
import com.shop.cloud.common.security.util.SecurityUtils;
import com.shop.cloud.upms.admin.service.SysTenantPackageService;
import com.shop.cloud.upms.admin.service.SysTenantService;
import com.shop.cloud.upms.common.entity.SysTenant;
import io.swagger.v3.oas.annotations.tags.Tag;
import io.swagger.v3.oas.annotations.Operation;
import lombok.AllArgsConstructor;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import jakarta.validation.Valid;
import java.time.LocalDateTime;

/**
 * <p>
 * 租户管理
 * </p>
 *
 * @author
 * @since 2018-01-20
 */
@RestController
@AllArgsConstructor
@RequestMapping("/tenant")
@Tag(description = "tenant", name = "租户管理模块")
public class SysTenantController {
	private final SysTenantService sysTenantService;
	private final SysTenantPackageService sysTenantPackageService;

	/**
	 * 分页查询
	 *
	 * @param page    参数集
	 * @param sysTenant 查询参数列表
	 * @return
	 */
	@Operation(summary = "分页查询")
	@GetMapping("/page")
	@PreAuthorize("@ato.hasAuthority('sys:tenant:index')")
	public R getPage(Page page, SysTenant sysTenant) {
		sysTenant.setType(CommonConstants.TENANT_TYPE_1);
		return R.ok(sysTenantService.page(page, Wrappers.query(sysTenant).in("id", SecurityUtils.getUser().getTenantIds())));
	}

	/**
	 * list查询
	 * @param sysTenant
	 * @return
	 */
	@Operation(summary = "list查询")
	@GetMapping("/list")
	public R getList(SysTenant sysTenant) {
		sysTenant.setType(CommonConstants.TENANT_TYPE_1);
		return R.ok(sysTenantService.list(Wrappers.query(sysTenant).lambda()
				.select(SysTenant::getId, SysTenant::getName)));
	}

	/**
	 * 通过ID查询
	 *
	 * @param id ID
	 * @return Systenant
	 */
	@Operation(summary = "通过ID查询")
	@GetMapping("/{id}")
//	@PreAuthorize("@ato.hasAuthority('sys:tenant:get')")
	public R getById(@PathVariable String id) {
		return R.ok(sysTenantService.getById(id));
	}

	/**
	 * 通过ID查询（服务间调用）
	 *
	 * @param id ID
	 * @return Systenant
	 */
	@Operation(summary = "通过ID查询（服务间调用）")
	@GetMapping("/inside/{id}")
	@Inside
	public R getByIdInside(@PathVariable String id) {
		return R.ok(sysTenantService.getById(id));
	}

	/**
	 * 添加
	 *
	 * @param sysTenant 实体
	 * @return ok/false
	 */
	@Operation(summary = "添加")
	@SysLog("添加租户")
	@PostMapping
	@PreAuthorize("@ato.hasAuthority('sys:tenant:add')")
	public R save(@Valid @RequestBody SysTenant sysTenant) {
		String id = String.valueOf(IdUtil.getSnowflake(1,2).nextId());
		TenantContextHolder.setTenantId(id);
		sysTenant.setId(id);
		sysTenant.setExpireTime(LocalDateTime.now());
		return R.ok(sysTenantService.save(sysTenant));
	}

	/**
	 * 删除
	 *
	 * @param id ID
	 * @return ok/false
	 */
	@Operation(summary = "删除")
	@SysLog("删除租户")
	@DeleteMapping("/{id}")
	@PreAuthorize("@ato.hasAuthority('sys:tenant:del')")
	public R removeById(@PathVariable String id) {
		return R.ok(sysTenantService.removeById(id));
	}

	/**
	 * 编辑
	 *
	 * @param sysTenant 实体
	 * @return ok/false
	 */
	@Operation(summary = "编辑")
	@SysLog("编辑租户")
	@PutMapping
	@PreAuthorize("@ato.hasAuthority('sys:tenant:edit')")
	public R update(@Valid @RequestBody SysTenant sysTenant) {
		sysTenant.setType(null);
		sysTenant.setStatus(null);
		sysTenant.setExpireTime(null);
		sysTenant.setPackageId(null);
		return R.ok(sysTenantService.updateById(sysTenant));
	}

	/**
	 * 编辑状态
	 *
	 * @param sysTenant 实体
	 * @return ok/false
	 */
	@Operation(summary = "编辑状态")
	@SysLog("编辑租户状态")
	@PutMapping("/status")
	@PreAuthorize("@ato.hasAuthority('sys:tenant:status')")
	public R updateStatus(@RequestBody SysTenant sysTenant) {
		SysTenant sysTenant1 = new SysTenant();
		sysTenant1.setId(sysTenant.getId());
		sysTenant1.setStatus(sysTenant.getStatus());
		return R.ok(sysTenantService.updateById(sysTenant1));
	}

	/**
	 * 编辑到期时间
	 *
	 * @param sysTenant 实体
	 * @return ok/false
	 */
	@Operation(summary = "编辑到期时间")
	@SysLog("编辑租户到期时间")
	@PutMapping("/expiretime")
	@PreAuthorize("@ato.hasAuthority('sys:tenant:expiretime')")
	public R updateExpireTime(@RequestBody SysTenant sysTenant) {
		if(sysTenant.getExpireTime() != null){
			SysTenant sysTenant1 = new SysTenant();
			sysTenant1.setId(sysTenant.getId());
			sysTenant1.setExpireTime(sysTenant.getExpireTime());
			sysTenantService.updateById(sysTenant1);
		}
		return R.ok();
	}

	/**
	 * 修改租户套餐
	 * @param sysTenant
	 * @return
	 */
	@Operation(summary = "修改租户套餐")
	@SysLog("修改租户套餐")
	@PutMapping("/package")
	@PreAuthorize("@ato.hasAuthority('sys:tenant:package')")
	public R updatePackageId(@RequestBody SysTenant sysTenant) {
		if(sysTenant.getPackageId() != null){
			SysTenant sysTenant1 = new SysTenant();
			sysTenant1.setId(sysTenant.getId());
			sysTenant1.setPackageId(sysTenant.getPackageId());
			sysTenantService.updateById(sysTenant1);
		}
		return R.ok();
	}

	/**
	 * list查询服务间调用
	 * @return
	 */
	@Operation(summary = "list查询服务间调用")
	@Inside
	@GetMapping("/inside/list")
	public R getListInside() {
		SysTenant sysTenant = new SysTenant();
		sysTenant.setType(CommonConstants.TENANT_TYPE_1);
		return R.ok(sysTenantService.list(Wrappers.query(sysTenant)));
	}

	/**
	 * 通过ID查询租户套餐服务间调用
	 * @return
	 */
	@Operation(summary = "通过ID查询租户套餐服务间调用")
	@Inside
	@GetMapping("/inside/package/{id}")
	public R getInsidePackage(@PathVariable String id) {
		String packageId = sysTenantService.getById(id).getPackageId();
		if(StrUtil.isBlank(packageId)){
			return R.ok(null);
		}
		return R.ok(sysTenantPackageService.getById(packageId));
	}

	/**
	 * 分页查询
	 *
	 * @param page    参数集
	 * @param sysTenant 查询参数列表
	 * @return
	 */
	@Operation(summary = "分页查询")
	@GetMapping("/outside/page")
	public R getUserPageOutside(Page page, SysTenant sysTenant) {
		sysTenant.setType(CommonConstants.TENANT_TYPE_1);
		return R.ok(sysTenantService.page(page, Wrappers.query(sysTenant).lambda()
				.select(SysTenant::getId,
						SysTenant::getName,
						SysTenant::getLogo,
						SysTenant::getHomeUrl,
						SysTenant::getPhone)));
	}

	/**
	 * 通过ID查询对外
	 *
	 * @param id ID
	 * @return Systenant
	 */
	@Operation(summary = "通过ID查询对外")
	@GetMapping("/outside/{id}")
	public R getByIdOutside(@PathVariable String id) {
		return R.ok(sysTenantService.getById(id));
	}

	/**
	 * 获取当前平台系统用户绑定的租户
	 * @param
	 * @return
	 */
	@Operation(summary = "获取当前平台系统用户绑定的租户")
	@GetMapping("/list/my")
	public R getMyList() {
		return R.ok(sysTenantService.listSysTenant(SecurityUtils.getUser().getId()));
	}

	/**
	 * 初始化指定租户的库
	 * @param id
	 * @return
	 */
	@Operation(summary = "初始化指定租户的库")
	@SysLog("初始化指定租户的库")
	@PostMapping("/database/init/{id}")
	@PreAuthorize("@ato.hasAuthority('sys:tenant:database:init')")
	public R initTenantDataBase(@PathVariable String id){
		sysTenantService.initTenantDataBase(id);
		return R.ok();
	}

	/**
	 *同步租户套餐菜单权限
	 * @param id
	 * @return
	 */
	@Operation(summary = "同步租户套餐菜单权限")
	@SysLog("同步租户套餐菜单权限")
	@PostMapping("/package/sync/{id}")
	@PreAuthorize("@ato.hasAuthority('sys:tenant:package:sync')")
	public R syncTenantPackage(@PathVariable String id){
		sysTenantService.syncTenantPackage(id);
		return R.ok();
	}

	/**
	 * 查询所属租户信息
	 *
	 * @param
	 * @return Systenant
	 */
	@Operation(summary = "查询所属租户信息")
	@GetMapping("/my")
//	@PreAuthorize("@ato.hasAuthority('sys:tenant:my')")
	public R getSysTenant() {
		return R.ok(sysTenantService.getById(TenantContextHolder.getTenantId()));
	}

	/**
	 * 数量查询
	 * @param sysTenant
	 * @return
	 */
	@Operation(summary = "数量查询")
	@GetMapping("/count")
	public R getCount(SysTenant sysTenant){
		return R.ok(sysTenantService.count(Wrappers.query(sysTenant)));
	}
}
